#ifndef _vector_traits_hpp_
#define _vector_traits_hpp_

/**\file vector_traits.hpp Contains metafunctions to query the size of a vector type
 *  and the scalar type of the field over which it is defined
 */

#include "math_common.hpp"
#include "math_traits.hpp"

namespace core {

    /** \brief Metafunctions to query vector type traits and algorithms for vectors
     */
    namespace math {

        //if T is a not supported vector type there is no template specialization
        //and template instanciation results in a compiler error
        /** \brief metafunction to query the dimension of a vector type
         *
         *  Usage: \code dimension<VectorType>::value \endcode
         *  Depending on whether the vector is of static (compile time defined) dimension
         *  or dynamic vector \a value is N or 0. If The vector has a dynamic storage, its 
         *  dimension can be queried at runtime like this:
         *  \code dimension<VectorType>::get(v) \endcode
         */
        template<class T>
            struct dimension
            : public boost::mpl::eval_if<is_scalar<T>,
                                    boost::mpl::size_t<1>,
                                    invalid_type<T>
                                    >::type
            {
                static std::size_t get(const T& t)
                {
                    return 0;
                }
            };

        /** \brief a metafunction that returns the field type of the vector
         *
         *  Usage: \code field<VectorType>::type \endcode
         */
        template<class T>
            struct field
            : public boost::mpl::if_<is_scalar<T>,
                                    T,
                                    invalid_type<T>
                                    >
            { };

    } // namespace math

} // namespace core

#include "detail/vector_traits_spec.hpp"

#endif // _vector_traits_hpp_
